এসকিউএলএলচেমি ডিফল্ট ডেটটাইম


174

এটি আমার ঘোষিত মডেল:

import datetime
from sqlalchemy import Column, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Test(Base):
    __tablename__ = 'test'

    id = Column(Integer, primary_key=True)
    created_date = DateTime(default=datetime.datetime.utcnow)

যাইহোক, আমি যখন এই মডিউলটি আমদানি করার চেষ্টা করি তখন আমি এই ত্রুটিটি পাই:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "orm/models2.py", line 37, in <module>
    class Test(Base):
  File "orm/models2.py", line 41, in Test
    created_date = sqlalchemy.DateTime(default=datetime.datetime.utcnow)
TypeError: __init__() got an unexpected keyword argument 'default'

আমি যদি একটি পূর্ণসংখ্যা টাইপ ব্যবহার করি তবে আমি একটি ডিফল্ট মান সেট করতে পারি। কি হচ্ছে?


1
এটি ব্যবহার করা উচিত নয়। ইউটিসি টাইমজোনগুলিতে ইউটাকনো একটি নিরীহ টাইমস্ট্যাম্প however
অ্যান্টি হাপালা

1
আমি জানি এই প্রশ্নটি অনেক আগে জিজ্ঞাসা করা হয়েছিল তবে আমি মনে করি যে আপনার উত্তরটি জেফ উইডম্যানের দেওয়া অন্যটিতে পরিবর্তিত হওয়া উচিত যখন অন্যটি রেকর্ডটি তৈরি হওয়ার সময় সারণী শ্রেণীর বিপরীতে সংজ্ঞায়িত হওয়ার সময় "সংকলন" সময় তারিখের সময় ব্যবহার করবে। আপনি যদি এএফকে হন তবে কমপক্ষে এই মন্তব্যটি অন্য প্রশ্নের সতর্কতার সাথে প্রতিটি প্রশ্নের জন্য মন্তব্যগুলি পরীক্ষা করার জন্য একটি সতর্কতা সরবরাহ করবে।
ডেভিড

উত্তর:


186

DateTimeইনপুট হিসাবে একটি ডিফল্ট কী নেই doesn't ডিফল্ট কীটি Columnফাংশনে একটি ইনপুট হওয়া উচিত । এটা চেষ্টা কর:

import datetime
from sqlalchemy import Column, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Test(Base):
    __tablename__ = 'test'

    id = Column(Integer, primary_key=True)
    created_date = Column(DateTime, default=datetime.datetime.utcnow)

13
এটা ঠিক নয় মডেল লোডের টাইমস্ট্যাম্পটি রেকর্ডটি যুক্ত হওয়ার পরিবর্তে সমস্ত নতুন রেকর্ডের জন্য ব্যবহৃত হবে।
স্কাইলাচ

8
@ স্কাইলিচ এই কোডটি সঠিক, আপনি এটি এখানে পরীক্ষা করতে পারেন: পেস্টবিন . com/ভিএলইইউকিটউন । datetime.datetime.utcnowকলব্যাক হিসাবে পরিচিত বলে মনে হচ্ছে।
বুक्स

1
আমি এই উত্তরটি ব্যবহার করেছি তবে মডেল লোডের টাইমস্ট্যাম্পটি সমস্ত নতুন রেকর্ডের জন্য ব্যবহৃত হচ্ছে।
স্কটিডেল্টা

105
@ স্কটডেল্টা: নিশ্চিত হয়ে নিন যে আপনি ব্যবহার করছেন না default=datetime.datetime.utcnow(); আপনি utcnowমডিউল লোড এ মূল্যায়নের ফলাফল নয়, ফাংশনটি পাস করতে চান ।
কর্মহীনতা

তবুও আমার পক্ষে কাজ হয়নি। : জেফ-widman পদ্ধতির আমার জন্য কাজfrom sqlalchemy.sql import func; created_date = Column(DateTime(timezone=True), server_default=func.now()
tharndt

396

আপনার ক্লায়েন্ট নয়, আপনার ডিবিতে টাইমস্ট্যাম্পগুলি গণনা করুন

বিচক্ষণতার জন্য, আপনি সম্ভবত সমস্ত datetimesঅ্যাপ্লিকেশন সার্ভারের চেয়ে আপনার ডিবি সার্ভার দ্বারা গণনা করতে চান । অ্যাপ্লিকেশনটিতে টাইমস্ট্যাম্প গণনা করা সমস্যার কারণ হতে পারে কারণ নেটওয়ার্ক ল্যাটেন্সিটি পরিবর্তনশীল, ক্লায়েন্টরা কিছুটা আলাদা ক্লক ড্রিফ্টের অভিজ্ঞতা অর্জন করে এবং বিভিন্ন প্রোগ্রামিং ল্যাঙ্গুয়েজ মাঝে মাঝে সময়কে কিছুটা আলাদাভাবে গণনা করে।

এসকিউএলএলচেমি আপনাকে পাস করার মাধ্যমে এটি করতে অনুমতি দেয় func.now()বা func.current_timestamp()(তারা একে অপরের উপাধি) যা ডিবিকে টাইমস্ট্যাম্প নিজেই গণনা করতে বলে।

এসকিউএএলএলচেমির ব্যবহার করুন server_default

অতিরিক্তভাবে, একটি ডিফল্ট যেখানে আপনি ইতিমধ্যে DB কে মান গণনা করতে বলছেন, সাধারণত server_defaultপরিবর্তে এটি ব্যবহার করা ভাল default। এটি এসকিউএলএলকেমিকে CREATE TABLEবিবৃতিটির অংশ হিসাবে ডিফল্ট মানটি পাস করতে বলে ।

উদাহরণস্বরূপ, আপনি যদি এই টেবিলের বিপরীতে কোনও অ্যাডহক স্ক্রিপ্ট লিখেন, এর server_defaultঅর্থ ব্যবহার করে আপনাকে আপনার স্ক্রিপ্টে ম্যানুয়ালি টাইমস্ট্যাম্প কল যুক্ত করার বিষয়ে চিন্তা করার দরকার নেই - ডাটাবেসটি এটি স্বয়ংক্রিয়ভাবে সেট হয়ে যাবে।

এসকিউএএলএলএকচির onupdate/server_onupdate

এসকিউএএলএলচেমি সমর্থন করে onupdateযাতে সারিটি আপডেট করা হয় যে কোনও সময় এটি একটি নতুন টাইমস্ট্যাম্প inোকায় । আবার, টাইমস্ট্যাম্প নিজেই গণনা করতে ডিবিকে বলা ভাল:

from sqlalchemy.sql import func

time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())

একটি server_onupdateপ্যারামিটার আছে, তবে এর বিপরীতে server_defaultএটি কোনও সার্ভারসাইড সেট করে না। এটি কেবল এসকিউএলচেমিকে বলেছে যে কোনও আপডেট হওয়ার পরে আপনার ডাটাবেসটি কলামটি পরিবর্তন করবে (সম্ভবত আপনি কলামটিতে একটি ট্রিগার তৈরি করেছেন ), সুতরাং এসকিউএএলএলচেমি রিটার্ন মানটি জিজ্ঞাসা করবে যাতে এটি সম্পর্কিত বিষয়টিকে আপডেট করতে পারে।

অন্য একটি সম্ভাব্য গোচা:

আপনি লক্ষ্য করে অবাক হতে পারেন যে আপনি যদি একক লেনদেনের মধ্যে একগুচ্ছ পরিবর্তন করেন তবে তাদের সবার একই টাইমস্ট্যাম্প থাকে। কারণ এসকিউএল স্ট্যান্ডার্ড নির্দিষ্ট করে যে CURRENT_TIMESTAMPলেনদেন শুরুর উপর ভিত্তি করে মানগুলি দেয়।

পোস্টগ্রি অ এসকিউএল-মানক প্রদান করে statement_timestamp()এবং clock_timestamp()যা না একটি লেনদেন মধ্যে পরিবর্তন। দস্তাবেজগুলি এখানে: https://www.postgresql.org/docs/current/static/function-datetime.html#FUNCTIONS-DETETIME-CURRENT

ইউটিসি টাইমস্ট্যাম্প

আপনি যদি ইউটিসি টাইমস্ট্যাম্প ব্যবহার করতে চান func.utcnow()তবে এসকিউএএলএলচেমি ডকুমেন্টেশনে এর জন্য বাস্তবায়নের একটি স্টাব সরবরাহ করা হবে । আপনার নিজের যথাযথ ড্রাইভার-নির্দিষ্ট ফাংশন সরবরাহ করতে হবে।


1
আমি এখন দেখেছি যে পোস্টগ্র্রেসকে বর্তমান সময়টি ব্যবহার করতে বলার উপায় আছে, কেবলমাত্র লেনদেন শুরুর সময় নয় ... এটি
পোস্টগ্রিস ডক্সে রয়েছে

2
সেখানে একটি ফানক.টুকন () বা এরকম কিছু আছে?
ইয়ারাসাইল

1
@ জেফভিডম্যান: আমাদের কি ইউটিউকনোর জন্য মাইএসকিএল বাস্তবায়ন আছে? আমি ডকুমেন্টেশনে কেবল এমএসকিএল এবং পোস্টরেগ
জাভাসা

1
এটি, সত্যিই, একটি দুর্দান্ত উত্তর!
জন মুতুমা

3
server_default=func.now()আমার জন্য কাজ, কিন্তু onupdate=func.now()করেনি। চেষ্টা করা onupdate=datetime.datetime.utcnow(বন্ধনী ব্যতীত), সেগুলিও সহায়তা করেনি
বিকাশ প্রসাদ

55

আপনি ডিফল্টর জন্য স্কেলচেমি বিল্টিন ফাংশনও ব্যবহার করতে পারেন DateTime

from sqlalchemy.sql import func

DT = Column(DateTime(timezone=True), default=func.now())

9
আপনি নিজেই ডাটাবেস দ্বারা হ্যান্ডেল করে তাই মান উইলের server_defaultপরিবর্তে ব্যবহার করতে পারেন default
rgtk

2
বর্ণনাকারী সংজ্ঞায়িত করার সময় ফানকুন.নু () কার্যকর করা হয় না, সুতরাং সমস্ত মডেল / শিশু (যদি এটি একটি বেস শ্রেণি হয়) একই ডিটি মান হয়। 'ডেটটাইম.ডেটটাইম.টাকনউ' এর মতো ফাংশন রেফারেন্সে পাস করে এটি প্রতিটিের জন্য পৃথকভাবে কার্যকর করা হয়। এটি 'তৈরি' বা 'আপডেট হওয়া' বৈশিষ্ট্যগুলির জন্য গুরুত্বপূর্ণ।
ধাতব ঝড়

10
@ মেটালস্টর্ম না, এটি সঠিক। sqlalchemy.sql.func একটি বিশেষ কেস যা বর্তমান সময়ে নয়, একটি স্ক্যালচেমি.এসএইচএল.ফানিউশনস.অন উদাহরণ দেয়। ডকসস.সেকলচেমি.আর.এইন
ক্রিস হার্ডি

কি করে timezone=True?
চেইমজি

1
@self থেকে ডকুমেন্টেশন : "যদি সত্য, এবং ব্যাকএন্ড দ্বারা সমর্থিত, 'টাইমস্ট্যাম্প সঙ্গে TIMEZONE' উত্পাদন করা হবে ব্যাক-এন্ডের যে সময় অঞ্চল সচেতন টাইমস্ট্যাম্প সমর্থন করি না জন্য কোনো প্রভাব নেই।।
ChaimG

7

আপনি সম্ভবত ব্যবহার করতে চান onupdate=datetime.nowযাতে আপডেটগুলিও last_updatedক্ষেত্রটি পরিবর্তন করে ।

পাইথন এক্সিকিউটড ফাংশনগুলির জন্য এসকিউএলএলচেমির দুটি ডিফল্ট রয়েছে।

  • default INSERT এ মান একবারে সেট করে
  • onupdateআপডেটের সাথে সাথে আপডেটের ফলাফলকে মান নির্ধারণ করে ।

আমি জানি না কেন, তবে কোনও কারণে onupdateআমার পক্ষে কিছু করে না।
বিকাশ প্রসাদ

1
: আমি শেষ পর্যন্ত এই করে Postgres ডিবি কাজ পেয়েছিলাম created_at = db.Column(db.DateTime, server_default=UtcNow())এবং updated_at = db.Column(db.DateTime, server_default=UtcNow(), onupdate=UtcNow())যেখানে UtcNowহিসাবে একটি ক্লাস হয় class UtcNow(expression.FunctionElement): type = DateTime()এবং আমরা আছে@compiles(UtcNow, 'postgresql') def pg_utc_now(element, compiler, **kw): return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
বিকাশ প্রসাদ

6

defaultশব্দ প্যারামিটার কলাম বস্তু দেওয়া উচিত।

উদাহরণ:

Column(u'timestamp', TIMESTAMP(timezone=True), primary_key=False, nullable=False, default=time_now),

ডিফল্ট মানটি কলযোগ্য হতে পারে, যা এখানে আমি নীচের মত সংজ্ঞায়িত করেছি।

from pytz import timezone
from datetime import datetime

UTC = timezone('UTC')

def time_now():
    return datetime.now(UTC)

কোথা time_nowথেকে আসে?
কে - এসই খারাপ

ধন্যবাদ! আমি ধরে নিয়েছিলাম যে সেই নামের সাথে একটি বিল্ট-ইন ফাংশন যা আমি কোনওভাবেই উপেক্ষা করেছি।
কে - এসই খারাপ

বাdatetime.datetime.utcnow
সার্কেফ

1

পোস্টগ্র্যাস এসকিউএল ডকুমেন্টেশন অনুসারে, https://www.postgresql.org/docs/9.6/static/function-datetime.html

now, CURRENT_TIMESTAMP, LOCALTIMESTAMP return the time of transaction.

এটি একটি বৈশিষ্ট্য হিসাবে বিবেচনা করা হয়: উদ্দেশ্যটি হ'ল একক লেনদেনকে "বর্তমান" সময়ের একটি ধারাবাহিক ধারণা থাকতে দেয়, যাতে একই লেনদেনের মধ্যে একাধিক পরিবর্তন একই সময়ের স্ট্যাম্প বহন করে।

আপনি যদি লেনদেনের টাইমস্ট্যাম্প না চান তবে আপনি স্টেটমেন্ট_টাইমস্ট্যাম্প বা ক্লক_টাইমস্ট্যাম্প ব্যবহার করতে চাইতে পারেন ।

statement_timestamp ()

বর্তমান বিবৃতিটির শুরুর সময়টি (বিশেষত ক্লায়েন্টের কাছ থেকে সর্বশেষতম কমান্ড বার্তা প্রাপ্তির সময়) প্রদান করে। statement_timestamp

clock_timestamp ()

প্রকৃত বর্তমান সময়টি ফেরত দেয়, এবং সেইজন্য এর মান একটি একক এসকিউএল কমান্ডের মধ্যেও পরিবর্তিত হয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.